﻿using System;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.Linq;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows;

namespace FraudMitigator
{
    public partial class PrintLetters : Form
    {
        int selectedRow;
        public string senderFirst = "";
        public string senderLast = "";
        public string senderAddr = "";
        public string senderCity = "";
        public string senderState = "";
        public string senderZip = "";
        public string senderPhone = "";
        public string payableTo = "";
        public string feeAmount = "";
        public bool canceled = false;
        string stringToPrint;
        Font printFont;

        public PrintLetters()
        {
            InitializeComponent();

            dataGridView1.DataSource = Queries.getOpenIncidents();

            foreach (int pos in Strings.printLettersColumnNames.Keys)
            {
                dataGridView1.Columns[pos].HeaderText = (string)Strings.printLettersColumnNames[pos];
            }
        }

        private void cancelBtn_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void dataGridView1_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
        {
            if (e.StateChanged == DataGridViewElementStates.Selected)
            {
                selectedRow = e.Row.Index;
            }
        }

        private void printLetterBtn_Click(object sender, EventArgs e)
        {
            canceled = false; // this will be changed to true by the LetterInfoForm form if necessary
            Letter letter = GetLetterData();

            if (!canceled)
            {
                DialogResult result = printDialog1.ShowDialog();

                // If the result is OK then print the document. 
                if (result == DialogResult.OK)
                {
                    
                    printFont = new System.Drawing.Font("Times New Roman", 10);
                    stringToPrint = letter.text;
                    printDocument1.Print();
                }
            }
        }

        public void BatchPrint(int letterToPrint)
        {
            TimeSpan twoWeekSpan = new TimeSpan(-15, 0, 0, 0);
            TimeSpan fourWeekSpan = new TimeSpan(-30, 0, 0, 0);
            DateTime now = DateTime.Now;
            DateTime twoWeeks = now.Add(twoWeekSpan);
            DateTime fourWeeks = now.Add(fourWeekSpan);
            ArrayList letterList = new ArrayList();

            using (var context = new DataContext(Strings.GetConnectionString()))
            {
                Table<Check> checks = context.GetTable<Check>();

                LetterInfoForm infoForm = new LetterInfoForm(this, letterToPrint == 3 ? 0 : letterToPrint);
                infoForm.ShowDialog();

                switch (letterToPrint)
                {
                    case 0:
                        var data = checks
                            .Where(z => z.CheckDate == now.Date);

                        foreach (Check check in data)
                        {
                            Letter letter = new Letter(
                            check.Account.AcctFName,
                            check.Account.AcctLName,
                            check.Account.AcctAddr + "\n" + check.Account.AcctCity + ", " + check.Account.AcctState + " " + check.Account.AcctZip,
                            check.CheckAmount,
                            check.CheckDate,
                            check.Account.Bank.BankName,
                            payableTo,
                            Convert.ToDecimal(feeAmount),
                            senderFirst + " " + senderLast,
                            SenderAddress(),
                            senderPhone
                        );

                            letterList.Add(letter);
                        }


                        break;
                    case 1:
                        data = checks
                            .Where(z => z.CheckDate.Date == twoWeeks.Date);

                        foreach (Check check in data)
                        {
                            Letter letter = new Letter(
                                check.Account.AcctFName,
                                check.Account.AcctLName,
                                check.Account.AcctAddr + "\n" + check.Account.AcctCity + ", " + check.Account.AcctState + " " + check.Account.AcctZip,
                                check.CheckAmount,
                                check.CheckDate.Date,
                                Convert.ToDecimal(feeAmount),
                                senderFirst + " " + senderLast,
                                SenderAddress(),
                                senderPhone
                            );

                            letterList.Add(letter);
                        }
                        break;
                    case 2:
                        data = checks
                            .Where(z => z.CheckDate.Date == fourWeeks.Date);

                        foreach (Check check in data)
                        {
                            Letter letter = new Letter(
                                check.Account.AcctFName,
                                check.Account.AcctLName,
                                check.Account.AcctAddr + "\n" + check.Account.AcctCity + ", " + check.Account.AcctState + " " + check.Account.AcctZip,
                                check.CheckDate,
                                senderFirst + " " + senderLast,
                                SenderAddress(),
                                senderPhone
                            );

                            letterList.Add(letter);
                        }
                        break;
                    case 3:
                        var firstLetters = checks
                            .Where(z => z.CheckDate == now);

                        var secondLetters = checks
                            .Where(z => z.CheckDate == twoWeeks);

                        var thirdLetters = checks
                            .Where(z => z.CheckDate == fourWeeks);

                        foreach (Check check in firstLetters)
                        {
                            Letter letter = new Letter(
                                check.Account.AcctFName,
                                check.Account.AcctLName,
                                check.Account.AcctAddr + "\n" + check.Account.AcctCity + ", " + check.Account.AcctState + " " + check.Account.AcctZip,
                                check.CheckAmount,
                                check.CheckDate,
                                check.Account.Bank.BankName,
                                payableTo,
                                Convert.ToDecimal(feeAmount),
                                senderFirst + " " + senderLast,
                                SenderAddress(),
                                senderPhone
                            );

                            letterList.Add(letter);
                        }

                        foreach (Check check in secondLetters)
                        {
                            Letter letter = new Letter(
                                check.Account.AcctFName,
                                check.Account.AcctLName,
                                check.Account.AcctAddr + "\n" + check.Account.AcctCity + ", " + check.Account.AcctState + " " + check.Account.AcctZip,
                                check.CheckAmount,
                                check.CheckDate,
                                Convert.ToDecimal(feeAmount),
                                senderFirst + " " + senderLast,
                                SenderAddress(),
                                senderPhone
                            );

                            letterList.Add(letter);
                        }

                        foreach (Check check in thirdLetters)
                        {
                            Letter letter = new Letter(
                                check.Account.AcctFName,
                                check.Account.AcctLName,
                                check.Account.AcctAddr + "\n" + check.Account.AcctCity + ", " + check.Account.AcctState + " " + check.Account.AcctZip,
                                check.CheckDate,
                                senderFirst + " " + senderLast,
                                SenderAddress(),
                                senderPhone
                            );

                            letterList.Add(letter);
                        }
                        break;
                }

                DialogResult result;
                if (letterList.Count > 0) result = printDialog1.ShowDialog();
                else 
                {
                    result = DialogResult.Cancel;
                    MessageBox.Show("There are currently no letters to be printed.");
                }

                // If the result is OK then print the document. 
                if (result == DialogResult.OK)
                {
                    MultiPrintDocument multiPrint = new MultiPrintDocument(letterList);
                    multiPrint.Print();
                }
            }
        }

        private Letter GetLetterData()
        {
            canceled = false;
            DataGridViewRow coll = dataGridView1.SelectedRows[0];
            string first = coll.Cells[0].Value.ToString();
            string last = coll.Cells[1].Value.ToString();
            decimal amount = Convert.ToDecimal(coll.Cells[2].Value);
            int letterSent = Convert.ToInt32(coll.Cells[3].Value);
            LetterInfoForm infoForm = new LetterInfoForm(this, letterSent);
            infoForm.ShowDialog();
            Letter letter = new Letter();

            if (!canceled)
            {
                using (var context = new DataContext(Strings.GetConnectionString()))
                {
                    Table<Check> checks = context.GetTable<Check>();

                    var data = checks
                        .Where(z => z.Account.AcctID == z.CheckAcctID)
                        .Where(z => z.Account.AcctFName == first
                        && z.Account.AcctLName == last
                        && z.CheckAmount == amount
                        && z.CheckLetterSent == letterSent)
                        .FirstOrDefault();

                    switch (letterSent)
                    {
                        case 0:
                            letter = new Letter(
                                data.Account.AcctFName,
                                data.Account.AcctLName,
                                data.Account.AcctAddr + "\n" + data.Account.AcctCity + ", " + data.Account.AcctState + " " + data.Account.AcctZip,
                                amount,
                                data.CheckDate.Date,
                                data.Account.Bank.BankName,
                                payableTo,
                                Convert.ToDecimal(feeAmount),
                                senderFirst + " " + senderLast,
                                SenderAddress(),
                                senderPhone
                            );
                            break;
                        case 1:
                            letter = new Letter(
                                data.Account.AcctFName,
                                data.Account.AcctLName,
                                data.Account.AcctAddr + "\n" + data.Account.AcctCity + ", " + data.Account.AcctState + " " + data.Account.AcctZip,
                                amount,
                                data.CheckDate.Date,
                                Convert.ToDecimal(feeAmount),
                                senderFirst + " " + senderLast,
                                SenderAddress(),
                                senderPhone
                            );
                            break;
                        case 2:
                            letter = new Letter(
                                data.Account.AcctFName,
                                data.Account.AcctLName,
                                data.Account.AcctAddr + "\n" + data.Account.AcctCity + ", " + data.Account.AcctState + " " + data.Account.AcctZip,
                                data.CheckDate.Date,
                                senderFirst + " " + senderLast,
                                SenderAddress(),
                                senderPhone
                            );
                            break;
                    }
                }
            }
            return letter;
        }

        private string SenderAddress()
        {
            return senderAddr + "\n" + senderCity + ", " + senderState + " " + senderZip;
        }

        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            int charactersOnPage = 0;
            int linesPerPage = 0;

            // Sets the value of charactersOnPage to the number of characters 
            // of stringToPrint that will fit within the bounds of the page.
            e.Graphics.MeasureString(stringToPrint, this.Font,
                e.MarginBounds.Size, StringFormat.GenericTypographic,
                out charactersOnPage, out linesPerPage);

            // Draws the string within the bounds of the page
            e.Graphics.DrawString(stringToPrint, this.Font, Brushes.Black,
                e.MarginBounds, StringFormat.GenericTypographic);

            // Remove the portion of the string that has been printed.
            stringToPrint = stringToPrint.Substring(charactersOnPage);

            // Check to see if more pages are to be printed.
            e.HasMorePages = (stringToPrint.Length > 0);
        }

        private void previewBtn_Click(object sender, EventArgs e)
        {
            canceled = false; // this will be changed to true by the LetterInfoForm form if necessary
            Letter letter = GetLetterData();

            if (!canceled)
            {
                printFont = new System.Drawing.Font("Times New Roman", 10);
                stringToPrint = letter.text;

                int taskBarHeight = Screen.PrimaryScreen.Bounds.Bottom - Screen.PrimaryScreen.WorkingArea.Bottom;
                int height = Screen.PrimaryScreen.Bounds.Height;
                int width = Screen.PrimaryScreen.Bounds.Width;

                printPreviewDialog1.Size = new Size((int)(width / 1.9), height - taskBarHeight);
                printPreviewDialog1.DesktopLocation = new Point(0, 0);
                printPreviewDialog1.ShowDialog();
            }
        }
    }
}
